package com.zhuxiaomei.aop;

import com.zhuxiaomei.annotation.AutoFill;
import com.zhuxiaomei.constant.AutoFillConstant;
import com.zhuxiaomei.entity.base.BaseEntity;
import com.zhuxiaomei.enumeration.OperationType;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.aspectj.lang.annotation.Aspect;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * @author hxm
 * @date 2024/11/18 10:39
 * @description
 */
@Aspect
@Component
@Slf4j
public class AutoFillAspect {

    //设置切入点
    @Pointcut("execution(* com.zhuxiaomei.mapper.*.*(..)) && @annotation(com.zhuxiaomei.annotation.AutoFill)")
    public void autoFillPointCut(){}


    @Before("autoFillPointCut()")
    public void autoFill(JoinPoint joinPoint){
//        log.info("公共字段填充");
        //获取方法签名对象
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //获取签名方法上的注解
        AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);
        //获得注解中的操作类型
        OperationType operationType = autoFill.value();
        //获取目标方法的参数
        Object[] args = joinPoint.getArgs();
        //约定：需要自动赋值的公共的字段放在参数位置第一个
        Object entity = args[0];
        //准备赋值数据
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime formattedDateTime = LocalDateTime.parse(now.format(formatter), formatter);
        Byte is_deleted = 0;

        if(operationType == OperationType.UPDATE){
            try {
                Method setUpdateTime = entity.getClass().getSuperclass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                setUpdateTime.invoke(entity, formattedDateTime);
            } catch (Exception e) {
                log.error("公共字段填充失败{}", e.getMessage());
            }
        }else if (operationType == OperationType.INSERT){
            try {

                Method setIsDeleted = entity.getClass().getSuperclass().getDeclaredMethod(AutoFillConstant.SET_IS_DELETED, Byte.class);
                Method setCreateTime = entity.getClass().getSuperclass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
                Method setUpdateTime = entity.getClass().getSuperclass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);

                setIsDeleted.invoke(entity, is_deleted);
                setCreateTime.invoke(entity, formattedDateTime);
                setUpdateTime.invoke(entity, formattedDateTime);
            } catch (Exception e) {
                log.error("公共字段填充失败{}", e.getMessage());
            }

        }
    }
}
